from django.core.cache import cache
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
# from rest_framework.viewsets import GenericViewSet
# from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
from rest_framework_jwt.settings import api_settings
from Rufe.models import UserProfile, UserToken, Products
from api.serializers import UserProfileSerializer, ProductsModelSerializer
# from .auth import MyAuthentication
from rest_framework.authentication import SessionAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import AllowAny, IsAuthenticatedOrReadOnly
from rest_framework.pagination import PageNumberPagination

"""
# class UserProfileViewSet(GenericViewSet, CreateModelMixin, ListModelMixin, UpdateModelMixin):
    GenericViewSet 继承了GenericAPIView和ViewSetMixin ,ViewSetMixin允许在url配置时进行绑定，例如使用router或者自己进行绑定
    GenericAPIView 继承自APIView：新增加了过滤、分页、序列化
    GenericAPIView 结合各种mixin可以组合成ListAPIView、RetrieveAPIView、等等，新增了get、post等方法

    从高到低的继承关系如下：
        GenericViewSet(viewset)  - drf
        GenericAPIView(generics) - drf
        APIView(views) - drf
        View - django
"""

"""
    访问方法	    对应的扩展类	            对应扩展类中的方法	    作用
    post	        CreateModelMixin	    create	            插入一条数据
    get	        ListModelMixin	        list	            展示数据列表
    get           RetrieveModelMixin      retrieve            返回单个数据
    put/patch	    UpdateModelMixin	    update	            更新所有/部分字段
    destroy       DestroyModelMixin       delete              删除部分字段
"""


class UserProfileViewSet(ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer

    authentication_classes = []
    permission_classes = []
    pagination_class = PageNumberPagination

    def get_authenticators(self):
        # 动态认证
        if self.action_map['get'] == "retrieve":
            self.authentication_classes = [SessionAuthentication, ]
        elif self.action_map['get'] == "list":
            self.authentication_classes = [JSONWebTokenAuthentication, ]
        return [auth() for auth in self.authentication_classes]

    def get_queryset(self):
        # 取出认证信息
        return self.queryset
    # methods 设置当前方法允许哪些http请求访问当前视图方法
    # detail 设置当前视图方法是否是操作一个数据
    # detail为True，表示路径名格式应该为 router_stu/{pk}/login/

    @action(methods=['get'], detail=True)
    def login(self, request):

        data = request.data
        username = data.get('username')
        password = data.get('password')

        import time
        # 校验用户名和密码
        user = UserProfile.objects.filter(username=username, password=password).first()
        if user.check_password(password):
            serializer = UserProfileSerializer(data=data)
            if serializer.is_valid(raise_exception=True):
                new_data = serializer.data
                # 记忆已登陆用户
                self.request.user = user.uid
                return Response(new_data, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)
        return Response('password error', status.HTTP_400_BAD_REQUEST)

        # 手动签发token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 将token存到redis缓存中
        cache.set(token, user, 60 * 60 * 24)
        user_id = str(user.uid).replace('-', '')
        # 响应数据
        data = {
            'token': token,
            'user_id': user_id,
            'user_name': user.username
        }
        headers = self.get_success_headers(data)

        return Response(data, status=status.HTTP_201_CREATED, headers=headers)

    @action(methods=['post'], detail=True)
    def register(self, request):
        serializer = UserProfileSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


#
class ProductsViewSet(ModelViewSet):
    queryset = Products.objects.all()
    serializer_class = ProductsModelSerializer
    authentication_classes = []
    permission_classes = []
    pagination_class = PageNumberPagination


